\chapter{Architettura ed Implementazione}\label{architettura}
L'applicazione è stata progettata seguendo un approccio modulare, per consentire una migliore leggibilità del codice e una più facile manutenibilità dello stesso. L'applicazione è composta da vari moduli:
\begin{description}
\item[Socket Manager:] gestione delle connessioni TCP.
\item[TorTella Protocol:] definizione del protocollo utilizzato.
\item[Http Manager:] creazione dei pacchetti http e relativi parser.
\item[Packet Manager:] intermediario tra il livello http e quello dei socket.
\item[Route Manager:] gestione delle regole di routing per i pacchetti di flooding.
\item[Servent:] strutture e funzionalità relative ai peer.
\item[Data Manager:] gestione dei dati della chat e degli utenti.
\item[Init:] modulo che consente il boot iniziale dell'applicazione.
\item[Controller:] gestione della comunicazione tra la GUI e gli strati sottostanti dell'applicazione.
\item[GUI:] generazione e gestione dell'interfaccia grafica.
\end{description}
Moduli di supporto:
\begin{description}	
\item[Utils:] generazione degli id, dump dei dati. 
\item[Common:] definizione dei tipi di dati utilizzati.
\item[Logger:] gestione del log dell'applicativo.
\item[Conf Manager:] gestione del file di configurazione.
\end{description}
\begin{figure}[H]
\begin{center}
\includegraphics[scale=0.5]{etc/architectural_overview.png}
\caption{Schema Architetturale}
\label{schemaarchitetturale}
\end{center}
\end{figure}
Nella figura \ref{schemaarchitetturale} si possono notare le interdipendenze tra moduli, in particolare l'importanza del modulo servent, che rappresenta il cuore dell'applicazione. Di fondamentale importanza è anche il controller, che gestisce la comunicazione tra la GUI e il resto dell'applicazione, nonchè il bootstrap con le relative connessioni iniziali ai peer.
\section{Socket Manager}
Lo strato software che gestisce l'instaurazione di una connessione di tipo persistente, e di tutto il relativo processo di comunicazione tra due o più nodi viene gestito dal file \texttt{socketmanager.c}. Poichè un servente deve comportarsi sia da client che da server. A tal proposito verranno analizzate i due processi di creazione dei socket.
\paragraph{create\_tcp\_socket()}
La funzione ha il compito di creare un socket di connessione remota, ovvero di instaurare una connessione remota ad un server TCP. Come è possibile capire, il tipo di comunicazione è orientata alla connessione, permettendo il trasferimento di un flusso continuo di dati.
Dopo la fase di inizializzazione del socket e l'apertura della connessione verso il server, viene eseguita la chiamata di sistema setsockopt() con il flag SO\_KEEPALIVE , al fine di caratterizzare la connessione precedentemente instaurata, ovvero creando un tipo di connessione persistente\footnote{Per connessione persistente si intende la presenza di un timer che viene reinizializzato ogni volta che avviene uno scambio di informazioni tra peer. Allo scadere del timer, il socket viene chiuso}.
\begin{lstlisting}
int create_tcp_socket(const char* dst_ip, int dst_port)
\end{lstlisting}
\paragraph{create\_listen\_tcp\_socket} 
Il compito di inizializzare il lato server del peer, creando un un socket d'ascolto, è affidato a questa funzione. Dopo la creazione del socket, vengono effettuate le chiamate bind() e listen(), le quali hanno il compito rispettivamente di inizializzare l'indirizzo IP locale e il relativo processo e di porre il socket dallo stato di CLOSED a quello di LISTEN. Come nel caso precedente viene utilizzata la syscall setosockopt(), la quale non si occupa solo di mantenere la connessione in uno stato permanente, ma anche di poter riutilizzare l'indirizzo locale. Usando il flag \texttt{SO\_REUSEADDR} fra la chiamata a socket() e quella a bind() si consente a quest'ultima di avere comunque successo anche se la connessione è attiva o si trova nello stato di TIME\_WAIT.  
Le operazioni riguardanti la ricezione del flusso di pacchetti e relativo invio sono gestite rispettivamente dalle funzioni: recv\_packet(), send\_packet(), le quali attraverso le chiamate di sistema standard della programmazione di rete si occupano di svolgere le funzioni di scrittura e lettura sui sockets d'interesse. Particolare attenzione deve essere rivolta alla funzione di lettura dei dati, in quanto è stato previsto un meccanismo di frammentazione dei pacchetti in blocchi, di dimensione massima (4096 byte) pari a quella impostata nel parametro buffer\_len, presente nel file di configurazione iniziale (tortella.conf).
\begin{lstlisting}
int create_listen_tcp_socket(const char* src_ip, int src_port)
\end{lstlisting}
Il modulo, oltre alle funzioni di creazione del socket, fornisce le funzioni relative all'invio e alla ricezione dei pacchetti.
\paragraph{send\_packet()}
Tale funzione consente la comunicazione tra i peer, in particolare consente di inviare dati tramite un socket. Per effettuare questa operazione viene utilizzata la chiamata di sistema \texttt{write()}.
\begin{lstlisting}
int send_packet(int sock_descriptor, char* buffer, int len)
\end{lstlisting}
\paragraph{recv\_packet()}
Quest'ultima funzione consente la ricezione dei dati da un peer. E' stata progettata rendendo possibile la ricezione di dati di dimensione illimitata (teoricamente), questo per rendere possibile il trasferimento di grossi file\footnote{funzionalità non implementata}. Il buffer passato come argomento deve essere non allocato per consentire alla funzione di allocare memoria dinamicamente.
\begin{lstlisting}
int recv_sized_packet(int sock_descriptor,char** buf, int max_len)
\end{lstlisting}
\section{TorTella Protocol}
Questo modulo contiene tutte le definizioni, le funzioni e le macro che implementano il protocollo TorTella. Ci sono tutte le definizioni dei pacchetti e dei descrittori trasportati, che sono i seguenti:
\begin{lstlisting}[frame=trBL]
#define PING_ID			0x01
#define LIST_ID			0x03
#define LISTHITS_ID		0x04
#define JOIN_ID			0x05
#define LEAVE_ID		0x06
#define MESSAGE_ID		0x07
#define SEARCH_ID		0x09
#define SEARCHHITS_ID	0x10
#define BYE_ID			0x11
#define CLOSE_ID 		0x12

//Status ID
#define ONLINE_ID	0x80
#define BUSY_ID		0x81
#define AWAY_ID		0x82

struct tortella_header {
	u_int8 id;		
	u_int4 desc_id;
	u_int8 sender_id;   
	u_int8 recv_id; 
	time_t timestamp;
	u_int4 desc_len; 
	u_int4 data_len; 
};
typedef struct tortella_header tortella_header;

struct ping_desc {
	u_int4 port;
	u_int1 status;
	//Campo dati: nickname
};
typedef struct ping_desc ping_desc;

struct list_desc {
	u_int8 chat_id;	
	u_int1 ttl;
	u_int1 hops;
};
typedef struct list_desc list_desc;

struct listhits_desc {
	u_int4 user_num;	
	u_int1 ttl;
	u_int1 hops;
	u_int8 chat_id;
	//Campo dati: elenco utenti della chat
};
typedef struct listhits_desc listhits_desc;

struct join_desc {
	u_int1 status;
	u_int8 user_id;
	u_int8 chat_id; 
	u_int4 port;
	char ip[16];
	u_int1 ttl;
	u_int1 hops;
	//Campo dati: nickname
};
typedef struct join_desc join_desc;

struct leave_desc {
	u_int8 user_id;
	u_int8 chat_id; 
	u_int1 ttl;
	u_int1 hops;
};
typedef struct leave_desc leave_desc;

struct message_desc {
	u_int8 chat_id;		
	//Campo dati: il msg
};
typedef struct message_desc message_desc;

struct search_desc {
	u_int1 ttl;
	u_int1 hops;
	//Campo dati: stringa ricerca
};
typedef struct search_desc search_desc;

struct searchhits_desc {
	u_int4 num_res;
	//Campo dati: risultati ricerca
};
typedef struct searchhits_desc searchhits_desc;

struct bye_desc {
};
typedef struct bye_desc bye_desc;

struct tortella_packet {
	tortella_header *header;
	char *desc;	//desc_len nell'header del pacchetto
	char *data;	//data_len nell'header del pacchetto
};
typedef struct tortella_packet tortella_packet;
\end{lstlisting}
Le varie funzioni sono descritte di seguito:
\paragraph{tortella\_bin\_to\_char()}
Questa funzione ha il compito di eseguire il parser del pacchetto tortella. In particolare prende in input da parametro il pacchetto, memorizzato nella sua struttura dati, e restituisce tutto il suo contenuto in un buffer di caratteri. Inoltre ritorna la lunghezza del buffer generato. Si è cercato di rendere tale operazione di conversione il più efficiente possibile, essendo una funzionalità utilizzata ogni volta che si invia un pacchetto.
\begin{lstlisting}
char *tortella_bin_to_char(tortella_packet *packet, u_int4 *len)
\end{lstlisting}
\paragraph{tortella\_char\_to\_bin()}
Tale funzione svolge le funzionalità di parser inverso rispetto alla funzione \texttt{tortella\_bin\_to\_char()}. La procedura riceve come parametro il buffer, contenente i dati, i quali vengono memorizzati nella struttura dati \texttt{tortella\_packet}. Questa funzione viene chiamata ogni volta che si riceve un pacchetto, per estrarre il suo contenuto e renderlo maggiormente accessibile dalle altre funzioni del programma.
\begin{lstlisting}
tortella_packet *tortella_char_to_bin(char *packet)
\end{lstlisting}
\section{Http Manager}
La gestione dei pacchetti HTTP, il cui protocollo è stato definito nel precedente capitolo, viene affrontato all'interno di questo modulo. Di seguito vengono riportate le strutture dati rappresentanti i pacchetti:
\begin{lstlisting}[frame=trBL]
struct http_header_request {
	char *request;
	char *user_agent;
	u_int4 range_start;
	u_int4 range_end;
	u_int4 content_len;
	char *connection;
};
typedef struct http_header_request http_header_request;

struct http_header_response {
	char *response;
	char *server;
	char *content_type;
	u_int4 content_len;
};
typedef struct http_header_response http_header_response;

struct http_packet {
	u_int4 type;
	http_header_request *header_request;
	http_header_response *header_response;
	tortella_packet *data;
	char *data_string;
	u_int4 data_len;
};
typedef struct http_packet http_packet;
\end{lstlisting}
Come è possibile notare sono state definite 3 tipi di strutture dati, dove le prime due sono utilizzate per la creazione dell'header a seconda se il messaggio da inviare sia di richiesta o di risposta, invece la terza struttura è utilizzata per definire l'intero pacchetto http. Sia nell'header di request che nell'header di response viene memorizzata, la lunghezza dell'intero pacchetto, la tipologia di dei dati contenuti(html,image..), che nel nostro caso saranno solamente di tipo binario e la versione del tipo di protocollo utilizzato (TorTella 0.1). Le uniche differenze presenti sono dovute al tipo di informazione (richiesta o risposta) contenuta negli header e all'identificazione nell'header request del tipo di connessione instaurata (di tipo persistente) tra due peer.
Al fine di rendere più agevole la creazione di un generico pacchetto sono state definite delle macro all'interno dell' header file:
\begin{lstlisting}[frame=trBL]
#define HTTP_REQ_GET		0x40
#define	HTTP_RES_GET		0x41
#define HTTP_REQ_POST		0x42
#define HTTP_RES_POST		0x43
#define HTTP_STATUS_OK		200
#define	HTTP_STATUS_CERROR	400
#define HTTP_STATUS_SERROR	500

#define HTTP_REQ_POST_LINE	"POST * HTTP/1.1"
#define HTTP_AGENT			"User-Agent: "
#define HTTP_REQ_RANGE		"Range: bytes="
#define HTTP_CONNECTION		"Connection: "
#define HTTP_CONTENT_TYPE	"Content-Type: "
#define HTTP_CONTENT_LEN	"Content-Length: "
#define HTTP_SERVER			"Server: "

#define HTTP_OK			"HTTP/1.1 200 OK"
#define HTTP_CERROR		"HTTP/1.1 400 Bad Request"
#define HTTP_SERROR		"HTTP/1.1 500 Internal Server Error"
\end{lstlisting}
Tutte le funzionalità relative al parsing dei dati contenuti nel pacchetto http sono svolte dalle seguenti funzioni:
\paragraph{http\_bin\_to\_char()}
La funzione si occupa di leggere i dati memorizzati in una struttura dati per poi salvare gli stessi in un buffer di caratteri. Nel momento in cui vi è la chiamata a tale funzione vengono passati come parametro sia l'intero pacchetto http che la sua lunghezza. L'algoritmo di parsing dopo aver controllato che il pacchetto ricevuto non sia vuoto provvede alla creazione di un buffer, il quale avrà dimensioni differenti  in base al tipo di messaggio contenente il pacchetto (REQ\_POST-REQ\_GET-RES\_POST-RES\_GET). Ogni campo dell'header, all'interno del buffer, viene delimitato con due caratteri separatori \texttt{$\setminus r\setminus n$}, in modo da permettere un'identificazione migliore delle varie informazioni, nel caso in cui si abbia la necessità di riconvertire tutti i dati nelle loro strutture d'appartenenza (\texttt{http\_char\_to\_bin}). Dopo di ciò viene fatto uso di un puntatore temporaneo, il quale dopo essere stato inizializzato con l'indirizzo del primo byte del buffer, viene spostato della sua lunghezza, in modo da poter appendere in seguito tutte le informazioni relative al campo dati del pacchetto http (vedi appendice).
\begin{lstlisting}
char *http_bin_to_char(http_packet *packet, int *len)
\end{lstlisting}
\paragraph{http\_char\_to\_bin()}
La funzione esegue il procedimento inverso della \texttt{http\_bin\_to\_char()}, in quanto prendendo da parametro un puntatore a caratteri, che contiene i campi dati del pacchetto http, effettua la conversione di questa nella relativa struttura d'appartenenza. Come nel caso precedente l'algoritmo suddivide il processo di parsing a seconda del tipo di pacchetto da ricostruire. Durante la conversione la funzione si occupa anche di preparare la struttura dati \texttt{tortella\_packet}, fornita dallo strato inferiore come contenitore del messaggio del pacchetto.
\begin{lstlisting}
http_packet *http_char_to_bin(const char *buffer)
\end{lstlisting}
\section{Packet Manager}
Il modulo in questione consente di creare ed inviare pacchetti TorTella e HTTP. Si può considerare come un insieme di API, volte a migliorare la leggibilità del codice, altrimenti si sarebbero dovute effettuare tutte le operazioni di invio manualmente. In particolare, le operazioni che ognuna di queste API svolge sono:
\begin{enumerate}
\item Preparazione dell'header del pacchetto TorTella; 
\item Preparazione del descrittore del pacchetto in base a ciò che si vuole inviare;
\item Preparazione dei dati (qualora presenti) del pacchetto TorTella;
\item Preparazione del pacchetto HTTP;
\item Conversione del pacchetto in un buffer di dati;
\item Invio del pacchetto;
\end{enumerate}
Di seguito si riportano le definizioni delle funzioni:
\begin{lstlisting}[frame=trBL]
int send_search_packet(u_int4 fd, u_int8 packet_id, u_int8 sender_id, u_int8 recv_id, u_int1 ttl, u_int1 hops, u_int4 string_len, char *string)

int send_searchhits_packet(u_int4 fd, u_int8 packet_id, u_int8 sender_id, u_int8 recv_id, u_int4 num_res, u_int4 res_len, char *res)

int send_join_packet(u_int4 fd, u_int8 packet_id, u_int8 sender_id, u_int8 recv_id, u_int1 status, u_int8 user_id, u_int8 chat_id, char *nick, u_int4 port, char *ip, u_int1 ttl, u_int1 hops)

int send_leave_packet(u_int4 fd, u_int8 packet_id, u_int8 sender_id, u_int8 recv_id, u_int8 user_id, u_int8 chat_id, u_int1 ttl, u_int1 hops)

int send_ping_packet(u_int4 fd, u_int8 sender_id, u_int8 recv_id, char *nick, u_int4 port, u_int1 status)

int send_list_packet(u_int4 fd, u_int8 sender_id, u_int8 recv_id, u_int1 ttl, u_int1 hops, u_int8 chat_id)

int send_listhits_packet(u_int4 fd, u_int8 sender_id, u_int8 recv_id, u_int4 user_num, u_int4 res_len, char *res, u_int8 chat_id)

int send_bye_packet(u_int4 fd, u_int8 sender_id, u_int8 recv_id)

int send_message_packet(u_int4 fd, u_int8 sender_id, u_int8 recv_id, u_int8 chat_id, u_int4 msg_len, char *msg)

int send_post_response_packet(u_int4 fd, u_int4 status, u_int4 data_len, char *data)

int send_get_request_packet(u_int4 fd, char *filename, u_int4 range_start, u_int4 range_end)

int send_get_response_packet(u_int4 fd, u_int4 status, u_int4 data_len, char *data)
\end{lstlisting}
\section{Route Manager}
Il modulo è stato implementato per la gestione delle regole di backward-routing dei pacchetti di tipo Search-SearchHits. Il peer da cui parte la richiesta deve ricevere un pacchetto SearchHits da ogni peer che ha ricevuto la richiesta; per realizzare tale meccanismo si utilizzano le regole di routing. In particolare, ogni peer che riceve un pacchetto Search deve memorizzare nella tabella di routing un record relativo al percorso che dovrà effettuare il SearchHits di risposta.
Per il funzionamento di questo meccanismo è stata utilizzata una hashtable contenente la struttura dati di seguito elencata:
\begin{lstlisting}[frame=trBL]
struct route_entry {
	u_int8 sender_id;
	u_int8 recv_id;
	u_int4 counter;
};
typedef struct route_entry route_entry;
\end{lstlisting}
Le regole vengono gestite attraverso le seguenti funzioni:
\begin{lstlisting}[frame=trBL]
int add_route_entry(u_int8 packet_id, u_int8 sender_id, u_int8 recv_id)

int del_route_entry(u_int8 id)

route_entry *get_route_entry(u_int8 packet_id)

u_int8 get_iddest_route_entry(u_int8 id)
\end{lstlisting}
\section{Servent}
L’architettura di un sistema \textit{peer to peer} prevede che ogni entità sia in grado di funzionare sia da client che da server. Ogni peer deve quindi essere realizzato come un servent. La parte server dovrà gestire i messaggi in arrivo dalla rete e quella client dovrà invece provvedere a inviare dati agli altri peer. Questo porta alla necessità di avere un sistema di gestione di tipo concorrente. L'utilizzo di thread, per la gestione concorrente delle richieste, ha permesso una maggiore agevolazione nella implementazione della comunicazione \textit{client server}.
\paragraph{servent\_data}
Per la comunicazione tra i thread relativi ad un peer è stata predisposta una struttura dati per la condivisione delle informazioni, ovvero la \texttt{servent\_data}:
\begin{lstlisting}[frame=trBL]
struct servent_data {
	u_int8 id;
	GQueue *queue;	
	GQueue *res_queue;
	char *ip;
	u_int4 port;
	u_int1 status;
	char *nick;
	time_t timestamp;
	
	GList *chat_list;

	pthread_rwlock_t rwlock_data;
	
	char *msg;
	u_int4 msg_len;
	
	GList *chat_res;
	u_int1 ttl;
	u_int1 hops;
	u_int8 packet_id;
	
	u_int1 is_online;
	u_int4 post_type;
	
	//FLOODING
	u_int8 user_id_req;
	u_int8 chat_id_req;
	u_int4 port_req;
	char *nick_req;
	char *ip_req;
	u_int1 status_req;
	char *title;
	u_int4 title_len;
};
typedef struct servent_data servent_data;
\end{lstlisting}
I campi della struttura presentata sono divisi in gruppi, in base al loro tipo di utilizzo:
\begin{itemize}
\item i campi che rappresentano le informazioni del peer, come: ip, porta, nickname, id;
\item i campi utilizzati per la comunicazione con il peer, come il tipo di pacchetto da inviare al peer associato alla struttura dati. Ad esempio, nel caso in cui il server thread dovesse riceve un pacchetto Search da uno specifico peer, tale campo dovrà assumere il valore \texttt{SEARCHHITS\_ID} per segnalare al client thread di inviare il pacchetto SearchHits di risposta;
\item i campi utilizzati per il flooding, ovvero servono alla ritrasmissione dei pacchetti ricevuti (Search, SearchHits, Join, Leave).
\end{itemize}
Per l'accesso alla struttura \texttt{servent\_data} di un peer vengono utilizzati dei meccanismi di lock, i quali consentono di evitare inconsistenza dei dati.\\

All'avvio dell'applicazione un'istanza del controller si occupa di chiamare la funzione \texttt{servent\_start()}, la quale ha il compito di inizializzare tutti i parametri del servente locale, di istanziare il lato server dello stesso, mettendolo in attesa di connessioni da altri peer, ed infine di avviare il suo lato client. A tale proposito all'interno della funzione vi sono tre chiamate di funzione,le quali hanno rispettivamente il compito di svolgere le attività elencate precedentemente. Di seguito vengono mostrati le dichiarazioni, presenti nell'header file, delle tre procedure con relativa spiegazione.
\paragraph{servent\_init()}
La funzione, come affermato in precedenza, si occupa di inizializzare i parametri del servente locale, identificando  il suo indirizzo ip, numero di porta e status iniziale, i quali vengono reperiti dal file di configurazione tortella.conf. Inoltre viene inizializzato il mutex relativo alla sua struttura dati
\begin{lstlisting}
int servent_init(char *ip, u_int4 port, u_int1 status)
\end{lstlisting}
\paragraph{servent\_start\_server()}
La funzione ha il compito di avviare il lato server del peer locale. Inizialmente viene creato il server, con la relativa coppia ip-porta, ricevuta da parametro; in seguito viene lanciato un thread, attivando l'esecuzione della funzione \texttt{servent\_listen()}, nella quale è presente un ciclo infinito, in cui viene creato un nuovo thread per ogni richiesta di connessione da nuovi peer.
\begin{lstlisting}
int servent_start_server(char *local_ip, u_int4 local_port)
\end{lstlisting}
\paragraph{servent\_init\_connection()}
La funzione ha il compito di inizializzare il lato client del servente locale e di avviare una connessione per ogni peer vicino presente nella lista \texttt{init\_servent}, la quale viene riempita con i dati relativi ai peer vicini inizialmente conosciuti. Il numero di peer considerati come “vicini” per ognuno dei nodi componenti la rete è stato scelto a priori e i relativi indirizzi ip e numero di porta sono salvati in un file di configurazione (init\_data.txt). 
\begin{lstlisting}  
int servent_init_connection(GList *init_servent)
\end{lstlisting}
\paragraph{servent\_connect()}
Questa funzione è stata realizzata per consentire la gestione della parte client di un peer, ovvero il \textit{client thread}. E' stata strutturata considerando la modalità di funzionamento a che deve avere. Infatti, essendo il thread che consente l'invio dei pacchetti ad uno specifico peer, sono state collocate le operazioni da svolgere all'interno di un ciclo while infinito. Grazie a questa tecnica è possibile inviare pacchetti ad un peer in qualsiasi momento, in particolare basta inserire in una coda apposita (spiegata più avanti) la richiesta da effettuare a tale thread. Tale funzione soddisfa le richieste sequenzialmente, effettuando l'invio e l'attesa di risposta.
Questo \textit{client thread} consente, ai moduli superiori, di rilevare errori di invio e ricezione dei peer destinatari. Infatti, grazie ad un'ulteriore coda di messaggi di risposta si possono controllare eventuali \textit{timeout} dei pacchetti. Tale coda viene riempita dalla \texttt{servent\_connect()} nel momento in cui riceve una conferma di ricezione pacchetto.
\begin{lstlisting}
void *servent_connect(void *parm)
\end{lstlisting}

\paragraph{servent\_listen()}
La parte \textit{server} di un peer è gestita da due funzioni (o meglio thread): \texttt{servent\_listen()} e \texttt{servent\_respond()}. La prima funzione in questione è la listen, la quale viene avviata una sola volta per ogni peer. In particolare, questa funzione non fa altro che accettare le richieste di connessione iniziali, il che si verifica quando un peer remoto invia un pacchetto di PING con fake ID al peer con la listen attiva. Tale listen, per ogni richiesta ricevuta, lancia un nuovo \textit{servent thread} che viene gestito dal thread \texttt{servent\_respond()}.
\begin{lstlisting}
void *servent_listen(void *parm)
\end{lstlisting}
\paragraph{servent\_respond()}
La \texttt{servent\_respond()} è il cuore del sistema e consente la ricezione di tutti i pacchetti inviati da uno specifico peer. Questi sono i passi generici eseguiti:
\begin{enumerate}
\item Il thread \texttt{servent\_listen()} lancia un nuovo thread che gestisce la funzione \texttt{servent\_respond()};
\item La funzione in questione entra in un ciclo while infinito;
\item Attende la ricezione di un pacchetto HTTP sulla porta specificata;
\item Pacchetto HTTP con dati TorTella ricevuto;
\item Riempimento della struttura dati \texttt{http\_packet} con i valori ricevuti nella stringa binaria;
\item Verifica correttezza pacchetto ricevuto;
\item Salta al flusso che gestisce il tipo di pacchetto ricevuto:
\begin{description}
	\item[Ping:] Può ricevere due tipi di Ping: con fake ID e con ID reale. Nel caso di fake ID invia il pacchetto di conferma e lancia un nuovo \textit{client thread} che invia un Ping con ID vero. Nel caso di ID reale invia un pacchetto di conferma ed un Ping.
	\item[Join:] Prima di tutto memorizza l'utente specificato dalla Join nella lista degli utenti della chat indicata. In seguito rinvia il pacchetto a tutti i vicini ed aggiunge delle regole di routing.
	\item[Leave:] Rimuove l'utente dalla lista degli utenti della chat specificata. In seguito rinvia il pacchetto ai suoi vicini.
	\item[Message:] Stampa il messaggio ricevuto.
	\item[Search:] Effettua la ricerca localmente e rinvia il pacchetto ai vicini. In seguito aggiunge delle regole di routing.
	\item[SearchHits:] Memorizza i risultati tornati dal pacchetto e preleva la regola di routing associata all'ID del pacchetto.
	\item[Bye:] Elimina l'utente da tutte le strutture dati e chiude eventuali finestre PM.
\end{description}
\item Invia eventualmente un pacchetto di conferma ricezione, se non è stato già inviato;
\item Torna al passo 3.
\end{enumerate}
Tale modulo comunica principalmente con: \textit{Packet Manager}, \textit{Http Manager}, \textit{Controller}.
\paragraph{servent\_send\_packet()}
Per richiedere l'invio dei pacchetti verso un peer è necessario chiamare tale funzione, la quale si occupa di inserire in una coda la richiesta di invio effettuata. In particolare opera nel seguente modo:
\begin{lstlisting}[frame=trBL]
void servent_send_packet(servent_data *sd) {
	if(sd != NULL) 
		g_queue_push_tail(sd->queue, (gpointer)sd);
}
\end{lstlisting}
Come si può notare dal codice, la funzione prede come parametro una struttura dati \texttt{servent\_data}. In realtà viene passata una copia della struttura originale utilizzata per condividere memoria; in questo modo si evitano richieste sovrapposte con eventuale invio di pacchetti errati. Se non si fosse attuata tale tecnica si sarebbe potuto incorrere in errore nel seguente caso: Il peer locale chiede di inviare un pacchetto di tipo Ping ad uno specifico servente; il peer locale chiede, inoltre, di inviare un pacchetto di tipo Join allo stesso servente; la \texttt{servent\_connect()} che riceve la richiesta di invio potrebbe inviare il pacchetto Ping con i dati del Join. Con il metodo adottato si evitano problemi di questo genere.
\paragraph{servent\_pop\_queue()}
Quest'altra funzione viene utilizzata dai \textit{client thread} per riceve le richieste di invio pacchetti.
\begin{lstlisting}[frame=trBL]
servent_data *servent_pop_queue(servent_data *sd) {
	servent_data *servent;
	if(sd==NULL || sd->queue==NULL) {
		logger(ALARM_INFO, "[servent_pop_queue]Queue error\n");
		return NULL;
	}
	//Ciclo utilizzato per attendere la richiesta di invio pacchetti
	while((servent = g_queue_pop_head(sd->queue))==NULL) {
		usleep(100000);
	}
	return servent;
}
\end{lstlisting}
Viene effettuata una operazione di \textit{pop} sulla coda ad intervalli di tempo precisi, in particolare ogni \texttt{100000} microsecondi. Il \textit{polling} potrebbe essere migliorato aggiungendo il supporto ai segnali, infatti basterebbe aggiungere al posto della \texttt{usleep()} la \texttt{pthread\_cond\_timedwait()} la quale si sarebbe sbloccata alla ricezione di un segnale o allo scadere del timer. Con quest'ultimo metodo si avrebbe un leggero incremento della prestazioni. Sono state realizzate push e pop anche per la coda dei messaggi di risposta, ma non verranno riportati essendo molto simili (ovvero \texttt{servent\_append\_response()} e \texttt{servent\_pop\_queue()}).
\paragraph{timer\_thread()}
Thread utilizzato per gestire il meccanismo di failure detection e per pulire la lista dei pacchetti ricevuti. L'intervallo di tempo è impostato nel file di configurazione. Tale funzione fa un elevato uso delle routine appena presentate.
\begin{lstlisting}[frame=trBL]
void *servent_timer(void *parm)
\end{lstlisting}

\section{Data Manager}
Il modulo datamanager si occupa di gestire tutti i meccanismi di accesso e di ricerca di una o più chat. Le principali strutture dati utilizzate sono chatclient e chat; la prima contiene le informazioni di un utente connesso ad una chat, invece la seconda mantiene le informazioni relative ad una specifica chat, considerando l'ID, il titolo, la lista di tutti gli utenti presenti in quel momento ed infine un mutex utilizzato per la gestione dell'accesso concorrente alla chat stessa. 
\begin{lstlisting}
struct chatclient {
	u_int8 id;
	char *nick;
	char *ip;
	u_int4 port;
};
typedef struct chatclient chatclient;

struct chat {
	u_int8 id;
	char *title;
	GHashTable *users;
	pthread_mutex_t mutex;
};
typedef struct chat chat;
\end{lstlisting}
Durante la fase di progettazione del modulo era stata prevista anche la possibilità di reperire o salvare le informazioni relative alle chat da un generico file, per questo motivo si è deciso di mantenere tutte le funzioni che realizzavano tale meccanismo, in previsione  di ulteriori sviluppi successivi. Di seguito viene riportato l'elenco dei prototipi di tali funzioni:
\begin{lstlisting}
int write_to_file(const char *filename, chat *chat_str, u_int4 mode)

int write_all(u_int4 mode)

int read_from_file(const char *filename)

int read_all(void)
\end{lstlisting}  
Dall'analisi dettagliata del modulo è possibile identificare due sezioni, la prima, come affermato precedentemente, si occupa degli accessi alle varie chat, invece la seconda ha il compito di gestire tutti gli algoritmi di parsing dei dati. Di seguito sono riportate le funzioni principali utilizzate per la gestione di una chat:
\begin{lstlisting}
int data_add_chat(u_int8 id, const char *title)

int data_del_chat(u_int8 id)

int data_add_user(u_int8 id, const char *nick, const char *ip, u_int4 port)

int data_add_users_to_chat(u_int8 chat_id, GList *users)

int data_del_user(u_int8 id)

int data_del_user_from_chat(u_int8 chat_id, u_int8 id)

chat *data_search_chat(const char *title)

chatclient *data_search_chatclient(const char *nick)
\end{lstlisting}
Tutte le funzioni,sopra riportate, sono state implementate tenendo conto del meccanismo di memorizzazione utilizzato. Nell'header file, in particolare, sono state definite due hashtable, le quali hanno il compito di memorizzare tutte le chat e tutti gli utenti presenti nella rete. In particolare tutte le funzioni adibite al parsing si occupano o di scandire il buffer contenente i dati memorizzandoli nelle relative strutture dati, o di effettuare il processo conversione inverso. Le informazioni relative alle chat sono salvate nel seguente formato:\\
\texttt{
\vdots\\
		|chat\_id;title;\\
		user\_id;nickname;indirizzo ip;numero porta;\\
		|chat\_id;title;\\
		user\_id;nickname;indirizzo ip;numero porta;\\
\vdots\\
}
Come è possibile notare ogni chat è delimitata dal carattere separatore \texttt{|}, il quale caratterizza l'inizio e la fine di ogni dato relativo alla chat identificata con il campo chat\_id e title. Nelle righe successive sono mostrati tutti gli utenti connessi alla chat con il relativo \textit{ID, nickname, indirizzo, ip} e numero di porta del socket associato.
La decisione di suddividere in tal modo ogni informazione nasce principalmente dalla necessità di identificare in modo semplice ogni dato e dalla necessità di sviluppare un parser abbastanza semplice e veloce.  

\section{Init}
Il modulo in questione consente di effettuare il bootstrap dell'applicazione, poichè permette ad un peer di conoscere i propri vicini (appositamente memorizzati in un file). Il file dei peer vicini è strutturato nel seguente modo:
\begin{lstlisting}
ip;porta;
ip;porta;
...
\end{lstlisting}
Per la memorizzazione dei record presenti all'interno del file è stata utilizzata la seguente struttura dati:
\begin{lstlisting}
struct init_data {
	char *ip;
	u_int4 port;
};
typedef struct init_data init_data;
\end{lstlisting}
e per la gestione di questi sono state utilizzate le seguenti funzioni.
\paragraph{init\_char\_to\_initdata()}
Riceve come parametro un buffer contenente un record del file e istanzia la struttura dati settando in modo opportuno ip e porta.
\begin{lstlisting}
init_data *init_char_to_initdata(char *buffer)
\end{lstlisting}
\paragraph{init\_read\_file()}
Legge il file in cui sono contenuti i record dei "vicini" e aggiunge tutti i peer presenti all'interno del file in una lista contenente strutture di tipo init\_data. Si serve della funzione \texttt{init\_char\_to\_init\_data()} per l'istanziazione delle strutture dati.
\begin{lstlisting}
GList *init_read_file(const char *filename)
\end{lstlisting}

\section{Controller}
Il \textit{Controller} ha il compito di inizializzare ed arrestare il sistema ed inoltre semplificare le interazioni tra la \textit{GUI} e il \textit{Servent}, in modo particolare per gestire al meglio i segnali scatenati da un utente durante l'esecuzione dell'applicazione. A tal proposito, si può operare una suddivisione delle funzioni per renderne più semplice la comprensione:
\begin{itemize}
\item funzioni per inizializzazione e chiusura dell'applicazione;
\item funzioni per l'aggiornamento corretto dell'interfaccia grafica;
\item funzioni per l'invio dei messaggi al servent.
\end{itemize}
\paragraph{controller\_init()}
Gestisce la fase di inizializzazione, che è composta dai seguenti passi:
\begin{enumerate}
\item lettura del file di configurazione;
\item avvio del logger;
\item lettura del file contenente i "vicini" conosciuti e memorizzazione di questi nell'apposita lista;
\item avvio del servent;
\item avvio del timer dedito alla gestione del meccanismo di failure detection.
\end{enumerate}
\begin{lstlisting}
int controller_init(const char *filename, const char *cache)
\end{lstlisting}
\paragraph{controller\_exit()}
Contrariamente alla \texttt{controller\_init()}, la funzione in questione ha il compito di gestire la chiusura dell'applicazione, effettuando i seguenti passi:
\begin{enumerate}
\item kill di tutti i thread del servente;
\item chiusura del file di log;
\end{enumerate}
\begin{lstlisting}
int controller_exit()
\end{lstlisting}
Del primo blocco di funzioni fa parte anche la \texttt{controller\_init\_gui()} (si veda a tal proposito l'appendice). Il secondo blocco comprende tutte le funzioni che permettono ad esempio di: visualizzare un messaggio ricevuto, aggiornare l'elenco dei partecipanti alla chat, aprire una nuova finestra in caso di ricezione di un messaggio privato. Di seguito si presentano le funzioni utilizzate:
\begin{lstlisting}
int controller_change_status(u_int1 status)

int controller_manipulating_status(u_int8 user_id, u_int1 status)

int controller_create(const char *title)

int controller_add_user_to_chat(u_int8 chat_id, u_int8 id)

int controller_rem_user_from_chat(u_int8 chat_id, u_int8 id)

int controller_add_msg_to_chat(u_int8 chat_id, char *msg)

int controller_add_msg(u_int8 sender_id, char *msg)
\end{lstlisting}
Le funzioni facenti parte dell'ultimo blocco sono fondamentali per il corretto funzionamento dell'applicazione, poichè preparano le strutture dati dei serventi e permettono l'invio dei pacchetti da parte del servente, inserendo le strutture dati in un'apposita coda in caso di invio e rimuovendo da un'altra in caso di ricezione di messaggi di risposta.
Di seguito si presentano le funzioni utilizzate:
\begin{lstlisting}
int controller_send_chat_users(u_int8 chat_id, u_int4 msg_len, char *msg)

int controller_send_subset_users(u_int8 chat_id, u_int4 msg_len, char *msg, GList *users)

int controller_send_pm(u_int4 msg_len, char *msg, u_int8 recv_id)

int controller_leave_all_chat()

int controller_connect_users(GList *users)

int controller_check_users_con(GList *users)

int controller_send_bye()

int controller_receive_bye()

u_int8 controller_search(const char *query)

int controller_join_flooding (u_int8 chat_id)

int controller_leave_flooding(u_int8 chat_id)
\end{lstlisting}
A tal proposito si presenta la funzione \texttt{send\_join\_packet()} come esempio:
\paragraph{send\_join\_packet()}
Il pacchetto di JOIN viene inviato in flooding, quindi per ogni peer conosciuto vengono effettuati i seguenti passi:
\begin{enumerate}
\item recupero delle informazioni associate all'utente a cui si vuole inviare il pacchetto;
\item controllo per evitare l'auto invio del pacchetto e l'invio ai fake id;
\item copia dei dati del peer in una struttura dati temporanea
\item impostazione dei campi della struttura dati temporanea (ad esempio: nickname, id utente, status utente, ip, porta, etc.);
\item inserimento della struttura dati nell'apposita coda che verrà gestita dal servente per l'invio del pacchetto
\item attesa della ricezione del messaggio di ok da parte del peer remoto
\item aggiornamento dei dati e della GUI.
\end{enumerate}
\paragraph{controller\_send\_bye()}
Tale funzione viene chiamata dall'applicazione quando viene richiesta la chiusura, in particolare effettua le seguenti operazioni:
\begin{enumerate}
\item Invia il LEAVE a tutti i peer vicini per tutte le chat a cui è connesso;
\item Attende le risposte;
\item Invia il BYE a tutti i peer vicini;
\item Attende le risposte;
\item Termina il processo.
\end{enumerate}
\section{Utils}
Il modulo Utils contiene la funzione che viene utilizzata per la generazione degli ID, ovvero:
\begin{lstlisting}[]
u_int8 generate_id(void) {
	char *addr;
	addr = get_mac_addr();
	int i=0, j=10;
	unsigned long res = 0;
	for(; i<6; i++, j*=10) {
		res += addr[i]*j;
	}
	res *= random();
	return (conf_get_gen_start()+((random())^res))*(res/2);
}
\end{lstlisting}
La generazione dell'identificativo univoco dei pacchetti e degli utenti, di tipo \texttt{unsigned long long}, avviene tramite una combinazione del \textit{MAC} della macchina, il valore generato dalla funzione pseudo-randomica \texttt{random()}\index{random()}, e dall'ID iniziale presente nel file di configurazione di ogni peer.
\section{Conf Manager}
Tale modulo consente la gestione del file di configurazione, consentendo di recuperare i valori desiderati tramite un insieme di semplici funzioni.
\section{Common}
Contiene le definizioni dei tipi di dati creati appositamente per \textit{TorTella}.
\section{GUI}
Essendo il modulo GUI di poca importanza relativamente al resto, si rimanda la lettura del codice in appendice.
